<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>album-step1</title>
    <style>
        html, body {
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
        }

        body {
            overflow: hidden;
        }

        canvas {
            width: 100%;
            height: 100%;
            background: #333;
        }

        .toolbar {
            position: fixed;
            bottom: 1rem;
            left: 0;
            right: 0;
            text-align: center;
        }

        button {
            font-size: large;
            padding: .7rem 2.2rem;
            margin: 0 1rem;
        }
    </style>
</head>
<body>
<canvas></canvas>
<div class="toolbar">
    <button onclick="prev()">上一张</button>
    <button onclick="next()">下一张</button>
</div>
<script>

    let index = 0;
    /** 最后加个方向调整2个方向的差异 */
    let orientation = -1;
    let factor = 1;
    const speed = 75;
    const images = [
        'images/1.webp',
        'images/2.webp',
        'images/3.webp',
        'images/4.webp',
        'images/5.webp',
        'images/6.webp',
        'images/7.webp',
        'images/8.webp',
    ]

    const canvas = document.querySelector('canvas');
    const ctx = canvas.getContext('2d');
    let temp = new Image();

    function init() {
        load(function (image) {
            draw(image, resize(image));
            temp = image;
        });
    }

    function load(callback) {
        const image = new Image();
        image.src = images[index];
        image.onload = function () {
            callback(image);
        }
    }

    function draw(image, size) {
        ctx.drawImage(image, size.dx, size.dy, size.width, size.height);
    }

    /** 根据显示区域分辨率和原图片分辨率，计算图片缩放后左边和宽高，这段代码只是随手写的，还有很大优化空间，仅做示范懒得修改了 */
    function resize(image) {
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
        let dx = 0;
        let dy = 0;
        let width = image.naturalWidth;
        let height = image.naturalHeight;
        if (canvas.width / canvas.height <= width / height) {
            height = height / width * canvas.width;
            width = canvas.width;
            dy = (canvas.height - height) / 2
        } else {
            width = width / height * canvas.height;
            height = canvas.height;
            dx = (canvas.width - width) / 2
        }
        return {
            dx: dx,
            dy: dy,
            width: width,
            height: height
        }
    }

    /** 算了累就累了 一起写了 */
    function next() {
        // 加入下标判断 防止越界
        if (index == images.length - 1) {
            alert('已经是最后一张了')
        } else if (index < images.length - 1) {
            orientation = -1;
            factor = 0.7;
            index++;
            // init();
            load(function (image) {
                const size1 = resize(temp);
                const size2 = resize(image);
                const end = size2.dx;
                // size1是旧图，起始位置不变，慢慢滑出屏幕
                // size2是新图，默认从屏幕外滑入，起始位置是原来dx再加一个屏幕宽度
                // end为最终位置
                size2.dx += window.innerWidth;
                animation(image, size1, size2, end);
            });
        }
    }

    /** 算了累就累了 一起写了 */
    function prev() {
        // 加入下标判断 防止越界
        if (index == 0) {
            alert('已经是第一张了')
        } else if (index > 0) {
            orientation = 1;
            factor = 0.7;
            index--;
            // init();
            load(function (image) {
                const size1 = resize(temp);
                const size2 = resize(image);
                const end = size2.dx;
                // size1是旧图，起始位置不变，慢慢滑出屏幕
                // size2是新图，默认从屏幕外滑入，起始位置是原来dx再加一个屏幕宽度
                // end为最终位置
                size2.dx -= window.innerWidth;
                animation(image, size1, size2, end);
            });
        }
    }

    /** 这个功能写起来累，只先写一个简单示范 */
    function animation(image, size1, size2, end) {
        // 这里思路是temp作为上一张图，传入的image作为下一张图，目前只考虑下一张按钮
        // 新图从右侧屏幕外开始进入，旧图从屏幕中间向左滑出屏幕
        // 开始之前清屏，避免上次动画留下什么残影
        ctx.clearRect(0, 0, canvas.width, canvas.height);

        console.log( size2.dx)
        draw(temp, size1);
        draw(image, size2);
        size1.dx += speed * orientation * factor;
        size2.dx += speed * orientation * factor;

        // 用于前慢后快的系数，这样写不准确，就意思一下，实际
        factor += 0.15;
        if (orientation > 0 ? size2.dx < end : size2.dx > end) {
            // 继续动画
            requestAnimationFrame(function () {
                // 层层递归
                animation(image, size1, size2, end);
            });
        } else {
            // 最后结尾肯定是 draw image
            size2.dx = end;
            // 开始之前清屏，避免上次动画留下什么残影
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            draw(image, size2);
            // 由于requestAnimationFrame存在线程问题，必须确认最后一次执行才赋image给temp缓存
            temp = image;
        }

    }

    window.onload = function () {
        // 加载第一张图片
        init();
    }

    window.onresize = function () {
        // 使用缓存数据避免加载延迟导致黑屏闪屏
        draw(temp, resize(temp));
    }
</script>
</body>
</html>
